from typing import Optional, Annotated

from fastapi import Query, Body
from pydantic import BaseModel, model_validator

from app.models import responses
from app.utils import types


class Pagination(BaseModel):
    """分页"""
    page: int
    page_size: int

    @model_validator(mode='before')
    @classmethod
    def __before(cls, data):
        data = types.safe_dict(data)
        data['page'] = types.safe_int(data.get('page', None), 1)
        data['page_size'] = types.safe_int(data.get('page_size', None), 20)
        return data

    @model_validator(mode='after')
    def __after(self):
        if self.page < 1:
            raise responses.FailureResponseError(-102, msg='当前页码不能小于 1')

        if not (1 <= self.page_size <= 50):
            raise responses.FailureResponseError(-102, msg='每页的记录范围仅只能是 1-50 条')

        return self


class AccountId(BaseModel):
    """接收账号 ID"""
    account_id: str

    @model_validator(mode='before')
    @classmethod
    def AccountId_before(cls, data):
        data = types.safe_dict(data)
        data['account_id'] = str(data.get('account_id', ''))
        return data

    @model_validator(mode='after')
    def AccountId_after(self):
        if len(self.account_id) != 12:
            raise responses.FailureResponseError(-102, msg='请输入正确的账号 ID')

        return self


AccountIdParams = Annotated[AccountId, Query()]
AccountIdJSON = Annotated[AccountId, Body()]


class AppId(BaseModel):
    """接收应用 ID"""
    app_id: Optional[int]

    @model_validator(mode='before')
    @classmethod
    def AppId_before(cls, data):
        data = types.safe_dict(data)
        data['app_id'] = types.safe_int(data.get('app_id', None), None)
        return data

    @model_validator(mode='after')
    def AppId_after(self):
        if self.app_id is None:
            raise responses.FailureResponseError(-102, msg='请输入格式正确的应用 ID')

        return self


AppIdParams = Annotated[AppId, Query()]
AppIdJSON = Annotated[AppId, Body()]


class CardTypeId(AppId):
    card_type_id: Optional[int]

    @model_validator(mode='before')
    @classmethod
    def CardTypeId_before(cls, data):
        data = types.safe_dict(data)
        data['card_type_id'] = types.safe_int(data.get('card_type_id', None), None)
        return data

    @model_validator(mode='after')
    def CardTypeId_after(self):
        if self.card_type_id is None:
            raise responses.FailureResponseError(-102, msg='请输入格式正确的卡种 ID')

        return self


CardTypeIdParams = Annotated[CardTypeId, Query()]
CardTypeIdJson = Annotated[CardTypeId, Body()]


class CardId(AppId):
    card_id: Optional[int]

    @model_validator(mode='before')
    @classmethod
    def CardId_before(cls, data):
        data = types.safe_dict(data)
        data['card_id'] = types.safe_int(data.get('card_id', None), None)
        return data

    @model_validator(mode='after')
    def CardId_after(self):
        if self.card_id is None:
            raise responses.FailureResponseError(-102, msg='请输入格式正确的卡密 ID')

        return self


CardIdParams = Annotated[CardId, Query()]
CardIdJSON = Annotated[CardId, Body()]


class DeviceId(AppId):
    device_id: Optional[int]

    @model_validator(mode='before')
    @classmethod
    def DeviceId_before(cls, data):
        data = types.safe_dict(data)
        data['device_id'] = types.safe_int(data.get('device_id', None), None)
        return data

    @model_validator(mode='after')
    def DeviceId_after(self):
        if self.device_id is None:
            raise responses.FailureResponseError(-102, msg='请输入格式正确的设备 ID')

        return self


DeviceIdParams = Annotated[DeviceId, Query()]
DeviceIdJSON = Annotated[DeviceId, Body()]


class FirewallRuleId(AppId):
    rule_id: Optional[int]

    @model_validator(mode='before')
    @classmethod
    def FirewallRuleId_before(cls, data):
        data = types.safe_dict(data)
        data['rule_id'] = types.safe_int(data.get('rule_id', None), None)
        return data

    @model_validator(mode='after')
    def FirewallRuleId_after(self):
        if self.rule_id is None:
            raise responses.FailureResponseError(-102, msg='请输入格式正确的规则 ID')

        return self


FirewallRuleIdParams = Annotated[FirewallRuleId, Query()]
FirewallRuleIdJSON = Annotated[FirewallRuleId, Body()]


class TrialRecordId(AppId):
    record_id: Optional[int]

    @model_validator(mode='before')
    @classmethod
    def TrialRecordId_before(cls, data):
        data = types.safe_dict(data)
        data['record_id'] = types.safe_int(data.get('record_id', None), None)
        return data

    @model_validator(mode='after')
    def TrialRecordId_after(self):
        if self.record_id is None:
            raise responses.FailureResponseError(-102, msg='请输入格式正确的试用记录 ID')

        return self


TrialRecordIdParams = Annotated[TrialRecordId, Query()]
TrialRecordIdJSON = Annotated[TrialRecordId, Body()]


class VersionId(AppId):
    version_id: Optional[int]

    @model_validator(mode='before')
    @classmethod
    def VersionId_before(cls, data):
        data = types.safe_dict(data)
        data['version_id'] = types.safe_int(data.get('version_id', None), None)
        return data

    @model_validator(mode='after')
    def VersionId_after(self):
        if self.version_id is None:
            raise responses.FailureResponseError(-102, msg='请输入格式正确的版本 ID')

        return self


VersionIdParams = Annotated[VersionId, Query()]
VersionIdJSON = Annotated[VersionId, Body()]


class SystemBoardId(BaseModel):
    board_id: Optional[int]

    @model_validator(mode='before')
    @classmethod
    def SystemBoardId_before(cls, data):
        data = types.safe_dict(data)
        data['board_id'] = types.safe_int(data.get('board_id', None), None)
        return data

    @model_validator(mode='after')
    def SystemBoardId_after(self):
        if self.board_id is None:
            raise responses.FailureResponseError(-102, msg='请输入格式正确的公告 ID')

        return self


SystemBoardIdParams = Annotated[SystemBoardId, Query()]
SystemBoardIdJSON = Annotated[SystemBoardId, Body()]
